package cn.sangedon.review.data.spider.impl;

import cn.hutool.http.HttpRequest;
import cn.sangedon.review.common.domain.data.SpiderMateData;
import cn.sangedon.review.common.domain.data.StockDayInfo;
import cn.sangedon.review.common.service.data.StockDayInfoService;
import cn.sangedon.review.common.service.data.TradingDateService;
import cn.sangedon.review.data.constant.SpiderEnum;
import cn.sangedon.review.data.spider.AbstractStockInfoSpider;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import java.math.BigDecimal;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.concurrent.atomic.AtomicInteger;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

/**
 * 上海日交易数据爬虫
 * 支持一次性获取当天所有交易数据，不支持历史数据查询
 *
 * @author dongliangqiong
 */
@Slf4j
@Component
public class StockOfDayShSpider extends AbstractStockInfoSpider {
    @Autowired
    private TradingDateService tradingDateService;

    @Autowired
    private StockDayInfoService stockDayInfoService;

    @Override
    public void runJob(List<SpiderMateData> spiderMateDataList) {
        spiderMateDataList.stream().filter(e -> e.getSpiderName().equals(SpiderEnum.SH_DAILY_HTTP.getName())).findFirst().ifPresent(e -> {
            addSchedule(e);
        });
    }

    @Override
    public void crawlData() {
        log.info("开始获取上海交易所日交易数据");
        List<String> tradingDay = tradingDateService.getLatestTradingDay(1);
        long count = stockDayInfoService.count(new LambdaQueryWrapper<StockDayInfo>().eq(StockDayInfo::getTradingDate, tradingDay.get(0))
                                                                                     .likeRight(StockDayInfo::getCode, "60"));
        if (count > 0) {
            log.info("最近交易日{}的上证日交易数据已获取", tradingDay.get(0));
            return;
        }

        AtomicInteger index = new AtomicInteger(0);
        while (!processData() && index.getAndIncrement() < 3) {
            log.info("重试获取上证日交易数据{}次", index.intValue());
        }
    }

    private boolean processData() {
        try {
            String spiderUrl = getSpiderMateData().getSpiderUrl();
            String body = HttpRequest.get(spiderUrl).execute().body();
            JSONObject result = null;
            if (body.startsWith("{") && body.endsWith("}")) {
                result = JSONObject.parseObject(body);
            } else {
                result = JSONObject.parseObject(body.substring(1, body.length() - 1));
            }

            DateFormat df = new SimpleDateFormat("yyyyMMdd");
            String dateStr = result.getString("date");
            Date date = df.parse(dateStr);
            List<StockDayInfo> list = new ArrayList<>();
            JSONArray data = result.getJSONArray("list");
            for (Object datum : data) {
                JSONArray array = (JSONArray) datum;
                StockDayInfo stockDayInfo = new StockDayInfo();
                stockDayInfo.setCode(array.getString(0));
                stockDayInfo.setName(array.getString(1));
                stockDayInfo.setOpeningPrice(new BigDecimal(array.getString(2).replace(",", "")));
                stockDayInfo.setPeakPrice(new BigDecimal(array.getString(3).replace(",", "")));
                stockDayInfo.setBottomPrice(new BigDecimal(array.getString(4).replace(",", "")));
                stockDayInfo.setClosingPrice(new BigDecimal(array.getString(5).replace(",", "")));
                stockDayInfo.setLastClosePrice(new BigDecimal(array.getString(6).replace(",", "")));
                stockDayInfo.setChangeRate(new BigDecimal(array.getString(7).replace(",", "")));
                stockDayInfo.setTradingVolume(new BigDecimal(array.getString(8).replace(",", "")).divide(new BigDecimal(100)));
                stockDayInfo.setTradingAmount(new BigDecimal(array.getString(9).replace(",", "")).divide(new BigDecimal(10000)));
                stockDayInfo.setChangeAmount(new BigDecimal(array.getString(11).replace(",", "")));
                stockDayInfo.setTradingDate(dateStr);
                list.add(stockDayInfo);
            }
            stockDayInfoService.saveOrUpdateBatch(list);
            log.info("上交所日交易数据保存成功:{}", list.size());
            return true;
        } catch (Exception e) {
            log.error("获取上海日交易数据失败:{}", e);
            return false;
        }
    }
}
